<script lang="ts" setup>
import * as XLSX from 'xlsx'
import { ElMessage, ElTable } from 'element-plus'
import { reactive, ref } from 'vue'
import qs from 'qs'
import { GetSPYejiData, GetYejiData } from '@/api/modules/retailOrder.ts'
import GetCacheData from '@/store/modules/NewPageCache'
import { GetOptionData } from '@/api/modules/weibanuser.ts'

const imgDomain = 'https://img1.eprhan.cc'
const cacheData = GetCacheData()
const PageNum = cacheData.GetCacheData('RetailOrderYeji').currentPage
const loading = ref(false)

// 数据列表
const dataList = reactive<any>({
  yejiList: [],
  spYejiList: [],
})

// 查询表单
const findFrom = ref({
  ...(cacheData.GetCacheData('RetailOrderYeji').fromData),
})

// 导航栏
function handleSelect(key: string) {
  findFrom.value.orderStatus = key
  cacheData.SetCacheData('RetailOrderYeji', PageNum, cacheData.GetCacheData('RetailOrderYeji').currentSize, findFrom.value)
}

// 查询
function Inquire() {
  if (findFrom.value.orderStatus === '1') {
    GetDataList()
    cacheData.SetCacheData('RetailOrderYeji', PageNum, cacheData.GetCacheData('RetailOrderYeji').currentSize, findFrom.value)
  }
  else {
    GetSPDataList()
    cacheData.SetCacheData('RetailOrderYeji', PageNum, cacheData.GetCacheData('RetailOrderYeji').currentSize, findFrom.value)
  }
}

// 获取业绩数据
async function GetDataList() {
  loading.value = true
  const params = qs.stringify({
    ...(findFrom.value.TimeWd && { TimeWd: findFrom.value.TimeWd }),
    ...(findFrom.value.YejiTime?.length > 0 && {
      TimeStart: findFrom.value.YejiTime[0],
      TimeEnd: findFrom.value.YejiTime[1],
    }),
    ...(findFrom.value.TagList?.length > 0 && {
      TagList: findFrom.value.TagList,
    }),
  })
  await GetYejiData(params).then((res: any) => {
    // console.log(res.data.items)
    if (res.succeeded) {
      dataList.yejiList = res.data
      const collect = {
        timeUnit: '汇总',
        totalAmount: Number.parseFloat(res.data.reduce((prev: number, cur: any) => prev + cur.totalAmount, 0).toFixed(2)),
        validTotalAmount: Number.parseFloat(res.data.reduce((prev: number, cur: any) => prev + cur.validTotalAmount, 0).toFixed(2)),
        buyersNumber: res.data.reduce((prev: number, cur: any) => prev + cur.buyersNumber, 0),
        averageAmount: Number.parseFloat(res.data.reduce((prev: number, cur: any) => prev + cur.averageAmount, 0).toFixed(2)),
        refundAmount: Number.parseFloat(res.data.reduce((prev: number, cur: any) => prev + cur.refundAmount, 0).toFixed(2)),
        refundProbability: Number.parseFloat(res.data.reduce((prev: number, cur: any) => prev + cur.refundProbability, 0).toFixed(2)),
      }
      collect.averageAmount = Number.parseFloat((collect.totalAmount / collect.buyersNumber).toFixed(2))
      collect.refundProbability = Number.parseFloat((collect.refundAmount / collect.totalAmount).toFixed(2))
      dataList.yejiList.unshift(collect)
      loading.value = false
    }
    else {
      ElMessage.error(`获取数据失败。${res.errors}`)
      loading.value = false
    }
  }).catch(() => {
    ElMessage.error('获取数据失败。')
    loading.value = false
  })
}
// 获取商品业绩数据
async function GetSPDataList() {
  loading.value = true
  const params = {
    ...(findFrom.value.SPYejiTime?.length > 0 && {
      TimeStart: findFrom.value.SPYejiTime[0],
      TimeEnd: findFrom.value.SPYejiTime[1],
    }),
  }

  await GetSPYejiData(params).then((res: any) => {
    // console.log(res.data.items)
    if (res.succeeded) {
      dataList.spYejiList = res.data
      loading.value = false
    }
    else {
      ElMessage.error(`获取数据失败。${res.errors}`)
      loading.value = false
    }
  }).catch(() => {
    ElMessage.error('获取数据失败。')
    loading.value = false
  })
}

async function ExportExcel() {
  let excelData = null
  let headerMapping = null
  if (findFrom.value.orderStatus === '1') {
    const params = {
      ...(findFrom.value.TimeWd && { TimeWd: findFrom.value.TimeWd }),
      ...(findFrom.value.YejiTime?.length > 0 && {
        TimeStart: findFrom.value.YejiTime[0],
        TimeEnd: findFrom.value.YejiTime[1],
      }),
    }

    excelData = await GetYejiData(params)
    const collect = {
      timeUnit: '汇总',
      totalAmount: Number.parseFloat(excelData.data.reduce((prev: number, cur: any) => prev + cur.totalAmount, 0).toFixed(2)),
      validTotalAmount: Number.parseFloat(excelData.data.reduce((prev: number, cur: any) => prev + cur.validTotalAmount, 0).toFixed(2)),
      buyersNumber: excelData.data.reduce((prev: number, cur: any) => prev + cur.buyersNumber, 0),
      averageAmount: Number.parseFloat(excelData.data.reduce((prev: number, cur: any) => prev + cur.averageAmount, 0).toFixed(2)),
      refundAmount: Number.parseFloat(excelData.data.reduce((prev: number, cur: any) => prev + cur.refundAmount, 0).toFixed(2)),
      refundProbability: Number.parseFloat(excelData.data.reduce((prev: number, cur: any) => prev + cur.refundProbability, 0).toFixed(2)),
    }
    collect.averageAmount = Number.parseFloat((collect.totalAmount / collect.buyersNumber).toFixed(2))
    collect.refundProbability = Number.parseFloat((collect.refundAmount / collect.totalAmount).toFixed(2))
    excelData.data.unshift(collect)

    headerMapping = {
      timeUnit: `时间（${findFrom.value.TimeWd === '1' ? '天' : findFrom.value.TimeWd === '2' ? '周' : '月'}）`,
      totalAmount: '成交金额',
      validTotalAmount: '去退成交金额',
      buyersNumber: '下单人数',
      averageAmount: '客单价（成交金额/下单人数）',
      refundAmount: '退款金额',
      refundProbability: '退款率（退款金额/成交金额）',
    } as { [key: string]: string }
  }
  else {
    const params = {
      ...(findFrom.value.SPYejiTime?.length > 0 && {
        TimeStart: findFrom.value.SPYejiTime[0],
        TimeEnd: findFrom.value.SPYejiTime[1],
      }),
    }

    excelData = await GetSPYejiData(params)

    headerMapping = {
      productId: '商品ID',
      productName: '商品名称',
      salePrice: '商品零售价',
      saleCount: '商品销量（含退款）',
      saleAmount: '销售金额（销量*价格）',
      refundCount: '退款数量',
      refundAmount: '退款金额（退款数量*价格）',
    } as { [key: string]: string }
  }
  // console.log(excelData.data)

  // 映射数据和合并order对象
  const newData = excelData.data.map((item: { [key: string]: any }) => {
    if (findFrom.value.orderStatus === '2') {
      const newItem = {
        productId: item.productInfo?.productId, // 将productId移动到前面
        productName: item.productInfo?.productName,
        salePrice: item.productInfo?.salePrice,
        // 复制其他属性到新对象
        ...item,
      }
      // 更新item为新的对象
      item = newItem

      delete item.productInfo
    }

    return Object.keys(item).reduce((newItem, key) => {
      (newItem as { [key: string]: any })[headerMapping[key] || key] = item[key]
      return newItem
    }, {})
  })
  // console.log(newData)
  // console.log('订单数量', newData)

  const wb = XLSX.utils.book_new()
  const ws = XLSX.utils.json_to_sheet(newData)
  // 设置列宽
  ws['!cols'] = [{ wch: 30 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 30 }, { wch: 20 }, { wch: 20 }, { wch: 15 }, { wch: 15 }, { wch: 30 }]
  // XLSX.utils.sheet_add_aoa(ws, [Object.values(headerMapping)], { origin: 'A1' })
  XLSX.utils.book_append_sheet(wb, ws, 'Sheet1')

  if (findFrom.value.orderStatus === '1') {
    XLSX.writeFile(wb, '业绩统计数据.xlsx')
  }
  else {
    XLSX.writeFile(wb, '商品统计数据.xlsx')
  }
}

const shortcuts = [
  {
    text: '今天',
    value: () => {
      const start = new Date()
      start.setHours(0, 0, 0, 0)
      const end = new Date()
      end.setHours(23, 59, 59, 999)
      return [start, end]
    },
  },
  {
    text: '昨天',
    value: () => {
      const start = new Date()
      start.setDate(start.getDate() - 1)
      start.setHours(0, 0, 0, 0)
      const end = new Date()
      end.setDate(end.getDate() - 1)
      end.setHours(23, 59, 59, 999)
      return [start, end]
    },
  },
  {
    text: '近一周',
    value: () => {
      const end = new Date()
      end.setHours(23, 59, 59, 999)
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
      start.setHours(0, 0, 0, 0)
      return [start, end]
    },
  },
  {
    text: '近一月',
    value: () => {
      const end = new Date()
      end.setHours(23, 59, 59, 999)
      const start = new Date()
      start.setMonth(start.getMonth() - 1)
      start.setHours(0, 0, 0, 0)
      return [start, end]
    },
  },
  {
    text: '近一年',
    value: () => {
      const end = new Date()
      end.setHours(23, 59, 59, 999)
      const start = new Date()
      start.setFullYear(start.getFullYear() - 1)
      start.setHours(0, 0, 0, 0)
      return [start, end]
    },
  },
  {
    text: '今年',
    value: () => {
      const end = new Date()
      end.setHours(23, 59, 59, 999)
      const start = new Date(new Date().getFullYear(), 0, 1)
      start.setHours(0, 0, 0, 0)
      return [start, end]
    },
  },
  {
    text: '去年',
    value: () => {
      const end = new Date(new Date().getFullYear(), 0, 1)
      end.setHours(0, 0, 0, 0)
      end.setTime(end.getTime() - 1)
      const start = new Date(new Date().getFullYear() - 1, 0, 1)
      start.setHours(0, 0, 0, 0)
      return [start, end]
    },
  },
]

// 标签筛选
const activeNames = ref([0])
const tagDialog = ref(false)
const tagOptionList = ref<any>([])
function Open() {
  if (findFrom.value.TagList.length > 0) {
    tagOptionList.value.forEach((item: any) => {
      item.name.forEach((nameItem: any) => {
        nameItem.value = false
      })
    })

    // 如果有值则设为true
    tagOptionList.value.forEach((item: any) => {
      item.name.forEach((nameItem: any) => {
        findFrom.value.TagList.forEach((tagItem: any) => {
          if (tagItem === nameItem.name) {
            nameItem.value = true
          }
        })
      })
    })
  }
  tagDialog.value = true
}

function OnChange(index: any, indexs: any) {
  tagOptionList.value[index].name[indexs].value = !tagOptionList.value[index].name[indexs].value
}

// 清空所有标签
function ClearTag() {
  tagOptionList.value.forEach((item: any) => {
    item.name.forEach((nameItem: any) => {
      nameItem.value = false
    })
  })
}
// 提交标签并筛选数据
function TagScreen() {
  tagDialog.value = false
  findFrom.value.TagList = tagOptionList.value.flatMap((group: any) => group.name) // 将所有组的name数组合并成一个数组
    .filter((item: any) => item.value === true) // 筛选出value为true的对象
    .map((item: any) => item.name) // 提取name属性
}

onMounted(async () => {
  try {
    await GetOptionData().then((res: any) => {
      if (res.succeeded) {
        tagOptionList.value = res.data
        tagOptionList.value.forEach((item: any) => {
          if (Array.isArray(item.name)) {
            // 将name数组转换为对象数组
            item.name = item.name.map((nameItem: any) => ({
              name: nameItem,
              value: false,
            }))
          }
        })
      }
      else {
        ElMessage.error(`查询失败。${res.errors}`)
      }
    })
  }
  catch (error) {
    ElMessage.error(`${error}`)
  }
})
</script>

<template>
  <div>
    <el-menu :default-active="findFrom.orderStatus" class="el-menu-demo" mode="horizontal" @select="handleSelect">
      <el-menu-item index="1">
        业绩统计
      </el-menu-item>
      <el-menu-item index="2">
        商品统计
      </el-menu-item>
    </el-menu>
    <PageMain>
      <SearchBar :show-toggle="false">
        <div class="header">
          <el-form label-positio="right" label-width="auto">
            <div class="from">
              <el-form-item v-if="findFrom.orderStatus === '1'" label="下单时间">
                <el-date-picker
                  v-model="findFrom.YejiTime" type="daterange" clearable value-format="YYYY-MM-DD HH:mm:ss"
                  range-separator="到" start-placeholder="开始日期" end-placeholder="结束日期"
                  :shortcuts="shortcuts"
                />
              </el-form-item>
              <el-form-item v-if="findFrom.orderStatus === '1'" label="时间维度">
                <el-select v-model="findFrom.TimeWd" placeholder="请选择时间维度">
                  <el-option label="日" value="1" />
                  <el-option label="周" value="2" />
                  <el-option label="月" value="3" />
                </el-select>
              </el-form-item>
              <el-form-item v-if="findFrom.orderStatus === '1'" label="标签">
                <el-select
                  v-model="findFrom.TagList"
                  multiple
                  placeholder="请筛选标签"
                >
                  <el-option
                    v-for="(item, index) in findFrom.TagList"
                    :key="index"
                    :label="item"
                    :value="item"
                  />
                </el-select>
              </el-form-item>
              <el-form-item v-if="findFrom.orderStatus === '2'" label="下单时间">
                <el-date-picker
                  v-model="findFrom.SPYejiTime" type="datetimerange" clearable value-format="YYYY-MM-DD HH:mm:ss"
                  range-separator="到" start-placeholder="开始日期" end-placeholder="结束日期"
                  :shortcuts="shortcuts"
                />
              </el-form-item>
            </div>
          </el-form>
          <div class="text-right">
            <el-button @click="Inquire">
              查询
            </el-button>
          </div>
        </div>
      </SearchBar>
      <ElDivider border-style="dashed" />
      <div class="mb-5 text-right">
        <el-button type="success" @click="ExportExcel">
          导出
        </el-button>
        <el-button @click="Open">
          标签筛选
        </el-button>
      </div>
      <ElTable v-if="findFrom.orderStatus === '1'" v-loading="loading" :data="dataList.yejiList" stripe style="width: 100%;" border>
        <el-table-column align="center" prop="timeUnit" :label="`时间（${findFrom.TimeWd === '1' ? '天' : findFrom.TimeWd === '2' ? '周' : '月'}）`" :width="findFrom.TimeWd === '2' ? '240' : '150'" />
        <el-table-column align="center" prop="totalAmount" label="成交金额" min-width="180" />
        <el-table-column align="center" prop="validTotalAmount" label="去退成交金额" min-width="180" />
        <el-table-column align="center" prop="buyersNumber" label="下单人数" min-width="100" />
        <el-table-column align="center" prop="averageAmount" label="客单价（成交金额/下单人数）" min-width="180" />
        <el-table-column align="center" prop="refundAmount" label="退款金额" min-width="180" />
        <el-table-column align="center" prop="refundProbability" label="退款率（退款金额/成交金额）" min-width="180" />
      </ElTable>
      <ElTable v-if="findFrom.orderStatus === '2'" v-loading="loading" :data="dataList.spYejiList" stripe style="width: 100%;" border>
        <el-table-column align="center" prop="productInfo.productId" label="商品ID" width="100" />
        <el-table-column header-align="center" prop="productInfo.productName" label="商品名称" min-width="440" show-overflow-tooltip />
        <el-table-column align="center" prop="cdnqrCodeBGPicUrl" label="商品图片" width="100">
          <template #default="scope">
            <el-avatar shape="square" :size="60" :src="imgDomain + scope.row.productInfo?.cdnProductPhotoPic" />
          </template>
        </el-table-column>
        <el-table-column align="center" prop="productInfo.salePrice" label="商品零售价" min-width="120" />
        <el-table-column align="center" prop="saleCount" label="商品销量（含退款）" min-width="180" sortable />
        <el-table-column align="center" prop="saleAmount" label="销售金额（销量*价格）" min-width="180" />
        <el-table-column align="center" prop="refundCount" label="退款数量" min-width="180" />
        <el-table-column align="center" prop="refundAmount" label="退款金额（退款数量*价格）" min-width="200" />
      </ElTable>
      <div style="height: 10px;" />
    </PageMain>

    <!-- 标签筛选 -->
    <el-dialog v-model="tagDialog" title="标签筛选" width="500" :destroy-on-close="true">
      <el-collapse v-model="activeNames">
        <el-collapse-item v-for="(item, index) in tagOptionList" :key="index" :title="item.group" :name="index">
          <div class="tag-box">
            <el-check-tag v-for="(items, indexs) in item.name" :key="indexs" :checked="items.value" type="primary" @change="OnChange(index, indexs)">
              {{ items.name }}
            </el-check-tag>
          </div>
        </el-collapse-item>
      </el-collapse>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="ClearTag">
            清空
          </el-button>
          <el-button type="primary" @click="TagScreen">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.header {
  display: grid;
  grid-template-columns: 5fr 1fr;

  .from {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
    grid-gap: 20px;
  }
}

.el-form-item {
  margin-bottom: 0;
}

.table-button {
  line-height: 42px;

  /* button {
    margin-bottom: 10px;
  } */
}

.tag-box {
  display: flex;
  flex-wrap: wrap;
  margin-top: 10px;

  span {
    margin-right: 10px;
    margin-bottom: 5px;
    font-size: 13px;
    font-weight: 400;
  }
}
</style>
